Passed
Pull Request — filestream (#173)
by
unknown
05:02
created

file-stream-processor.ts ➔ getBufferSize   A

Complexity

Conditions 3

Size

Total Lines 5
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 3
1
import { getId3Tag, Header } from './id3-tag'
2
3
// const FileBufferSize = 20 * 1024 * 1024
4
5
// Must be at least Header.size which is the min size to detect an ID3 header.
6
// Naming it help identifying the code handling it.
7
const RolloverBufferSize = Header.size
8
9
const MinBufferSize = RolloverBufferSize + 1
10
const DefaultFileBufferSize = RolloverBufferSize + 20 * 1024 * 1024
11
12
export class Id3TagStreamProcessor {
13
    private buffer: Buffer
14
    private tags: Buffer[] = []
15
    private rolloverSize = 0
16
    continue = false
17
18
    constructor(bufferSize?: number) {
19
        this.buffer = Buffer.alloc(getBufferSize(bufferSize))
20
    }
21
22
    getReadBuffer() {
23
        return this.buffer.subarray(this.rolloverSize)
24
    }
25
26
    processReadBuffer(readSize: number) {
27
        let data = this.buffer.subarray(0, this.rolloverSize + readSize)
28
29
        // TODO extract that to id3-tag
30
        // Remove tags from `data`
31
        let missingData = Buffer.alloc(0)
32
        let tag
33
        while((tag = getId3Tag(data))) {
34
            const tagBuffer = Buffer.alloc(tag.size)
35
            tag.data.copy(tagBuffer)
36
            data = tag.after
37
            missingData = tagBuffer.subarray(tag.data.length)
38
        }
39
40
        // Exclude rollover window on the last part
41
        this.rolloverSize = Math.min(RolloverBufferSize, data.length, readSize)
42
        const rolloverStart = data.length - this.rolloverSize
43
        const rolloverData = Buffer.from(data.subarray(rolloverStart))
44
45
        // Update rollover window
46
        rolloverData.copy(this.buffer)
47
48
        this.continue = this.rolloverSize !==0 || missingData.length !== 0
49
50
        return missingData
51
    }
52
53
    getTags() {
54
        return this.tags
55
    }
56
}
57
58
function getBufferSize(bufferSize?: number) {
59
    return Math.max(
60
        bufferSize ?? DefaultFileBufferSize,
61
        MinBufferSize
62
    )
63
}
64
65
export class Id3TagRemover {
66
    private buffer: Buffer
67
    private rolloverSize = 0
68
    continue = false
69
70
    constructor(bufferSize?: number) {
71
        this.buffer = Buffer.alloc(getBufferSize(bufferSize))
72
    }
73
74
    getReadBuffer() {
75
        return this.buffer.subarray(this.rolloverSize)
76
    }
77
78
    processReadBuffer(readSize: number) {
79
        let data = this.buffer.subarray(0, this.rolloverSize + readSize)
80
81
        // TODO extract that to id3-tag
82
        // Remove tags from `data`
83
        let missingBytes = 0
84
        const parts = Array.from((function*() {
85
            let tag
86
            while((tag = getId3Tag(data))) {
87
                yield tag.before
88
                data = tag.after
89
                missingBytes = tag.missingBytes
90
            }
91
        })())
92
93
        // Exclude rollover window on the last part
94
        this.rolloverSize = Math.min(RolloverBufferSize, data.length, readSize)
95
        const rolloverStart = data.length - this.rolloverSize
96
        const rolloverData = Buffer.from(data.subarray(rolloverStart))
97
        parts.push(data.subarray(0, rolloverStart))
98
99
        const writeBuffer = Buffer.concat(parts)
100
101
        // Update rollover window
102
        rolloverData.copy(this.buffer)
103
104
        this.continue = this.rolloverSize !==0 || missingBytes !== 0
105
106
        return {
107
            skipBuffer: Buffer.alloc(missingBytes),
108
            writeBuffer
109
        }
110
    }
111
}
112